1
2
3
4 package joeq.ClassLib.Common.java.util.zip;
5
6 import java.util.zip.DataFormatException;
7
8 /***
9 * InflaterDynHeader
10 *
11 * @author John Whaley <jwhaley@alum.mit.edu>
12 * @version $Id: InflaterDynHeader.java 1451 2004-03-09 06:27:08Z jwhaley $
13 */
14 class InflaterDynHeader {
15
16 private static final int LNUM = 0;
17 private static final int DNUM = 1;
18 private static final int BLNUM = 2;
19 private static final int BLLENS = 3;
20 private static final int LENS = 4;
21 private static final int REPS = 5;
22
23 private static final int repMin[] = { 3, 3, 11 };
24 private static final int repBits[] = { 2, 3, 7 };
25
26
27 private byte[] blLens;
28 private byte[] litdistLens;
29
30 private InflaterHuffmanTree blTree;
31
32 private int mode;
33 private int lnum, dnum, blnum, num;
34 private int repSymbol;
35 private byte lastLen;
36 private int ptr;
37
38 private static final int[] BL_ORDER =
39 { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
40
41 public InflaterDynHeader()
42 {
43 }
44
45 public boolean decode(StreamManipulator input) throws DataFormatException
46 {
47 decode_loop:
48 for (;;)
49 {
50 switch (mode)
51 {
52 case LNUM:
53 lnum = input.peekBits(5);
54 if (lnum < 0)
55 return false;
56 lnum += 257;
57 input.dropBits(5);
58
59 mode = DNUM;
60
61 case DNUM:
62 dnum = input.peekBits(5);
63 if (dnum < 0)
64 return false;
65 dnum++;
66 input.dropBits(5);
67
68 num = lnum+dnum;
69 litdistLens = new byte[num];
70 mode = BLNUM;
71
72 case BLNUM:
73 blnum = input.peekBits(4);
74 if (blnum < 0)
75 return false;
76 blnum += 4;
77 input.dropBits(4);
78 blLens = new byte[19];
79 ptr = 0;
80
81 mode = BLLENS;
82
83 case BLLENS:
84 while (ptr < blnum)
85 {
86 int len = input.peekBits(3);
87 if (len < 0)
88 return false;
89 input.dropBits(3);
90
91 blLens[BL_ORDER[ptr]] = (byte) len;
92 ptr++;
93 }
94 blTree = new InflaterHuffmanTree(blLens);
95 blLens = null;
96 ptr = 0;
97 mode = LENS;
98
99 case LENS:
100 {
101 int symbol;
102 while (((symbol = blTree.getSymbol(input)) & ~15) == 0)
103 {
104
105
106
107 litdistLens[ptr++] = lastLen = (byte) symbol;
108
109 if (ptr == num)
110 {
111
112 return true;
113 }
114 }
115
116
117 if (symbol < 0)
118 return false;
119
120
121 if (symbol >= 17)
122 {
123
124
125 lastLen = 0;
126 }
127 else
128 {
129 if (ptr == 0)
130 throw new DataFormatException();
131 }
132 repSymbol = symbol-16;
133 mode = REPS;
134 }
135
136
137 case REPS:
138 {
139 int bits = repBits[repSymbol];
140 int count = input.peekBits(bits);
141 if (count < 0)
142 return false;
143 input.dropBits(bits);
144 count += repMin[repSymbol];
145
146
147 if (ptr + count > num)
148 throw new DataFormatException();
149 while (count-- > 0)
150 litdistLens[ptr++] = lastLen;
151
152 if (ptr == num)
153 {
154
155 return true;
156 }
157 }
158 mode = LENS;
159 continue decode_loop;
160 }
161 }
162 }
163
164 public InflaterHuffmanTree buildLitLenTree() throws DataFormatException
165 {
166 byte[] litlenLens = new byte[lnum];
167 System.arraycopy(litdistLens, 0, litlenLens, 0, lnum);
168 return new InflaterHuffmanTree(litlenLens);
169 }
170
171 public InflaterHuffmanTree buildDistTree() throws DataFormatException
172 {
173 byte[] distLens = new byte[dnum];
174 System.arraycopy(litdistLens, lnum, distLens, 0, dnum);
175 return new InflaterHuffmanTree(distLens);
176 }
177 }